package com.yhk.wuchat.common.common.aspect;

import cn.hutool.core.util.StrUtil;
import com.yhk.wuchat.common.common.annotation.RedissonLock;
import com.yhk.wuchat.common.common.service.LockService;
import com.yhk.wuchat.common.common.util.SpElUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * @version 1.0
 * @Author moresuo
 * @Date 2024/4/14 16:31
 * @注释
 */
@Component
@Aspect
@Order(0)//确保比事务切面先执行
public class RedissonLockAspect {
    @Resource
    private LockService lockService;


    @Around("@annotation(redissonLock)")
    public Object around(ProceedingJoinPoint joinPoint, RedissonLock redissonLock) throws Throwable {
        //获取method对象
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        //分布式锁的前缀默认为类+方法名
        String prefix= StrUtil.isBlank(redissonLock.prefixKey())? SpElUtils.getMethodKey(method) :redissonLock.prefixKey();
        String key=SpElUtils.parseApEl(method,joinPoint.getArgs(),redissonLock.key());
        return lockService.executeWithLock(prefix + ":" + key, redissonLock.waitTime(), redissonLock.timeUnit(), joinPoint::proceed);
    }
}
